package org.testis.gui.mvc;

import org.testis.gui.mvc.controller.testdesign.TreeController;
import org.testis.gui.mvc.controller.testdesign.PopupController;
import org.testis.gui.mvc.controller.dynamicmap.DynamicMapTreeController;
import org.testis.gui.mvc.controller.dynamicmap.DynamicMapPopupController;
import org.testis.data.AtofModuleConstants;
import org.testis.gui.mvc.controller.*;
import org.testis.gui.mvc.model.dynamicmap.DynamicMapPopupModel;
import org.testis.gui.mvc.model.dynamicmap.DynamicMapTreeModel;
import org.testis.gui.mvc.model.testdesign.PopupModel;
import org.testis.gui.mvc.model.testdesign.TreeModel;
import org.testis.gui.mvc.utilities.DebugLogger;
import org.testis.gui.mvc.utilities.ValidationUtils;
import org.testis.gui.mvc.view.dynamicmap.DynamicMapPopupView;
import org.testis.gui.mvc.view.testdesign.PopupViewPanel;
import org.testis.gui.mvc.view.testdesign.TreeViewPanel;
import org.testis.utils.AtofActiveMqConnectionFactory;
import org.testis.utils.JarUtils;
import org.testis.utils.PropertyFileProvider;
import java.awt.BorderLayout;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.IOException;
import java.util.LinkedList;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import org.orm.PersistentException;
import org.orm.cfg.JDBCConnectionSetting;
import org.testis.orm.manager.TestisDbPersistentManager;
import org.testis.utils.middleware.DynamicMap;
import org.testis.utils.middleware.TestDesign;

/**
 *
 * @author Cahit Emir Erel
 */
public class Main implements WindowListener {

    JFrame m_displayFrame;

    public Main(String owner) {
        System.setOut(DebugLogger.getInstance());
        String headerText = getGuiHeaderText();

        m_displayFrame = new JFrame(headerText);
        m_displayFrame.addWindowListener(this);
        TreeModel treeModel = new TreeModel();
        PopupModel popupModel = new PopupModel();
        DynamicMapTreeModel dynamicMapTreeModel = new DynamicMapTreeModel();
        DynamicMapPopupModel dynamicMapPopupModel = new DynamicMapPopupModel();

        TreeController treeController = new TreeController(owner);
        PopupController popupController = new PopupController();
        TestDesignControllerList.newInstance(treeController,
                popupController,
                m_displayFrame);

        try {
            TestDesignControllerList.newInstance().getDbConfigController().
                    startLoader();
        } catch (Exception ex) {
            System.out.println("Error:" + ex.getMessage());
        }
        loadUserDefinedDbDefinitions();

        DynamicMapTreeController dynamicMapTreeController =
                new DynamicMapTreeController();
        DynamicMapPopupController dynamicMapPopupController =
                new DynamicMapPopupController();
        DynamicMapControllerList.newInstance(dynamicMapTreeController,
                dynamicMapPopupController,
                m_displayFrame);

        TreeViewPanel treeViewPanel = new TreeViewPanel();
        PopupViewPanel popupViewPanel = new PopupViewPanel();
        DynamicMapPopupView dynamicMapPopupView = new DynamicMapPopupView();

        treeController.addView(treeViewPanel);
        popupController.addView(popupViewPanel);
        dynamicMapTreeController.addView(treeViewPanel);
        dynamicMapPopupController.addView(dynamicMapPopupView);
        treeController.addModel(treeModel);
        popupController.addModel(popupModel);
        dynamicMapTreeController.addModel(dynamicMapTreeModel);
        dynamicMapPopupController.addModel(dynamicMapPopupModel);

        treeModel.initDefault();
        dynamicMapTreeModel.initDefault();

        m_displayFrame.getContentPane().add(popupViewPanel);
        m_displayFrame.getContentPane().add(treeViewPanel,
                BorderLayout.CENTER);
        m_displayFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        m_displayFrame.pack();
        if (isValidSqlConnection()) {
            TestDesign.newInstance();
            DynamicMap.newInstance();
        }
        m_displayFrame.setEnabled(false);
        m_displayFrame.setVisible(true);
    }

    private boolean hasLastLoadedTrees() {
        try {
            /*loading last loaded  tree*/
            PropertyFileProvider propFile = new PropertyFileProvider();
            propFile.loadPropertiesFile(AtofModuleConstants.ATOF_VENDOR_HOME +
                    "/" +
                    "user.props",
                    false);
            String val = propFile.getProperty("SELECT_SUITE");
            if (val != null && val.trim().length() > 0) {
                return true;
            }

            val = propFile.getProperty("SELECT_DYNAMIC_MAP");
            if (val != null && val.trim().length() > 0) {
                return true;
            }

        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return false;
    }

    private void addLastLoadedTrees() {
        try {
            /*loading last loaded  tree*/
            PropertyFileProvider propFile = new PropertyFileProvider();
            propFile.loadPropertiesFile(AtofModuleConstants.ATOF_VENDOR_HOME +
                    "/" +
                    "user.props",
                    false);
            String val = propFile.getProperty("SELECT_SUITE");
            if (val != null) {
                if (!val.trim().equals("")) {
                    String[] loadedTestDesigns = val.split("#");
                    System.out.println("Test tree count to be loaded:" + loadedTestDesigns.length);
                    for (int i = 0; i < loadedTestDesigns.length; i++) {
                        System.out.println("Loading test tree:" + loadedTestDesigns[i]);
                        TestDesignControllerList.newInstance().getTreeController().
                                operationLoadTreeFromDb(loadedTestDesigns[i]);
                    }
                }

            }
            val = propFile.getProperty("SELECT_DYNAMIC_MAP");
            if (val != null) {
                if (!val.equals("")) {
                    String[] loadedDynamicMaps = val.split("#");
                    System.out.println("Dynamic map tree count to be loaded:" + loadedDynamicMaps.length);
                    for (int i = 0; i < loadedDynamicMaps.length; i++) {
                        System.out.println("Loading Dynamic map tree with id:" + loadedDynamicMaps[i]);
                        DynamicMapControllerList.newInstance().
                                getDynamicMapTreeController().
                                operationLoadTreeFromDatabase(Integer.parseInt(
                                loadedDynamicMaps[i]));
                    }
                }

            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void addLastLoadedTrees(LinkedList<String> suiteList, LinkedList<String> dynamicMapList) {
        try {
            for (int i = 0; i < suiteList.size(); i++) {
                System.out.println("Loading test tree:" + suiteList.get(i));
                TestDesignControllerList.newInstance().getTreeController().
                        operationLoadTreeFromDb(suiteList.get(i));
            }

            for (int i = 0; i < dynamicMapList.size(); i++) {
                System.out.println("Loading Dynamic map tree with id:" + dynamicMapList.get(i));
                String[] splitArr = dynamicMapList.get(i).split(" -- ");
                if (splitArr.length == 0) {
                    continue;
                }

                int dynamicMapID = 0;
                try {
                    dynamicMapID = Integer.parseInt(splitArr[0]);
                } catch (NumberFormatException nfe) {
                    nfe.printStackTrace();
                    continue;
                }
                DynamicMapControllerList.newInstance().getDynamicMapTreeController().operationLoadTreeFromDatabase(dynamicMapID);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
        } catch (Exception e) {
        }
        new Main("Emir");
    }

    public boolean isValidSqlConnection() {
        JDBCConnectionSetting settings = null;
        try {
            settings =
                    org.testis.orm.manager.TestisDbPersistentManager.getJDBCConnectionSetting();
        } catch (PersistentException ex) {
            ex.printStackTrace();
        }
        String dbUrl = "jdbc:mysql://localhost/atof";
        String dbUserName = "root";
        String dbPassword = "12345";
        if (settings != null) {
            dbUrl = settings.getConnectionURL();
            dbUserName = settings.getUserName();
            dbPassword = settings.getPassword();
        }
        return ValidationUtils.checkMySqlConnection(dbUrl,
                dbUserName,
                dbPassword);
    }

    public boolean isValidActiveMqConnection() {
        PropertyFileProvider propFile = new PropertyFileProvider();
        boolean isLoaded =
                propFile.loadPropertiesFile(AtofModuleConstants.ATOF_VENDOR_HOME +
                "/" +
                "database.props",
                false);
        String activemqUrl =
                "tcp://localhost:61616?wireFormat.maxInactivityDuration=5000";
        if (isLoaded) {
            activemqUrl = "tcp://" + propFile.getProperty(
                    "ACTIVEMQ_URL") + ":61616?wireFormat.maxInactivityDuration=5000";
        }
        return AtofActiveMqConnectionFactory.checkActiveMqConnection(activemqUrl);
    }

    @Override
    public void windowOpened(WindowEvent e) {
        m_displayFrame.setEnabled(true);
        if (isValidSqlConnection()) {
            if (hasLastLoadedTrees()) {
                TestDesignControllerList.newInstance().getSelectSuiteController().startLoader();
                LinkedList<String> selectedSuites = TestDesignControllerList.newInstance().getSelectSuiteController().getSelectedTestSuites();
                LinkedList<String> selectedDynamicMaps = TestDesignControllerList.newInstance().getSelectSuiteController().getSelectedDynamicMaps();
                addLastLoadedTrees(selectedSuites, selectedDynamicMaps);
            }
        } else {
            JOptionPane.showMessageDialog(null,
                    "Could not connect to mysql server",
                    "Error",
                    JOptionPane.ERROR_MESSAGE);
        }
        if (!isValidActiveMqConnection()) {
            JOptionPane.showMessageDialog(null,
                    "Could not connect to activemq server",
                    "Error",
                    JOptionPane.ERROR_MESSAGE);
        }
        return;
    }

    @Override
    public void windowClosing(WindowEvent e) {
        try {
            String[] loadedTestDesigns = TestDesignControllerList.newInstance().
                    getTreeController().getLoadedTrees();
            String[] loadedDynamicMaps = DynamicMapControllerList.newInstance().
                    getDynamicMapTreeController().getLoadedTrees();
            PropertyFileProvider propFile = new PropertyFileProvider();
            propFile.loadPropertiesFile(AtofModuleConstants.ATOF_VENDOR_HOME +
                    "/" +
                    "user.props",
                    false);
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < loadedTestDesigns.length; i++) {
                if (sb.length() == 0) {
                    sb.append(loadedTestDesigns[i]);
                } else {
                    sb.append("#" + loadedTestDesigns[i]);
                }
            }
            propFile.putProperty("SELECT_SUITE",
                    sb.toString(),
                    "last selected test suites");
            sb = new StringBuilder();
            for (int i = 0; i < loadedDynamicMaps.length; i++) {
                if (sb.length() == 0) {
                    sb.append(loadedDynamicMaps[i]);
                } else {
                    sb.append("#" + loadedDynamicMaps[i]);
                }
            }
            propFile.putProperty("SELECT_DYNAMIC_MAP",
                    sb.toString(),
                    "last selected dynamic maps");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    @Override
    public void windowClosed(WindowEvent e) {
        try {
            TestisDbPersistentManager.instance().getSession().flush();
            TestisDbPersistentManager.instance().getSession().clear();
            TestisDbPersistentManager.instance().getSession().close();
        } catch (PersistentException ex) {
            ex.printStackTrace();
        }
    }

    @Override
    public void windowIconified(WindowEvent e) {
    }

    @Override
    public void windowDeiconified(WindowEvent e) {
    }

    @Override
    public void windowActivated(WindowEvent e) {
    }

    @Override
    public void windowDeactivated(WindowEvent e) {
    }

    private String getGuiHeaderText() {
        String appPath = getClass().getProtectionDomain().getCodeSource().
                getLocation().getPath();
        String atofjarPath = "";
        if (!appPath.endsWith(".jar")) {//running with netbeans
            String[] jarFiles = System.getProperty("java.class.path").split(System.getProperty("path.separator"));
            for (int i = 0; i < jarFiles.length; i++) {
                String tmp = jarFiles[i];
                if (tmp.contains("atof.jar")) {
                    atofjarPath = tmp;
                    break;
                }
            }
        } else {//jar running externally
            int index = appPath.lastIndexOf("/");
            appPath = appPath.substring(0,
                    index + 1);
            atofjarPath = appPath + "lib/atof.jar";
        }
        String impVersion = "N/A";
        String specificationVersion = "N/A";
        try {
            impVersion =
                    JarUtils.getJarImplementationVersion(atofjarPath);
        } catch (IOException ex) {
        }
        try {
            specificationVersion =
                    JarUtils.getJarSpecificationVersion(atofjarPath);
        } catch (IOException ex) {
        }
        return "ATOF Designer GUI Alpha -v" +
                specificationVersion +
                " - r" + impVersion;
    }

    private void loadUserDefinedDbDefinitions() {
        PropertyFileProvider propFile =
                new PropertyFileProvider();
        boolean isLoaded =
                propFile.loadPropertiesFile(AtofModuleConstants.ATOF_VENDOR_HOME +
                "/" +
                "database.props",
                false);
        if (isLoaded) {
            String dbUrl = propFile.getProperty("DATABASE_URL");
            String dbUserName = propFile.getProperty("DATABASE_USERNAME");
            String dbPassword = propFile.getProperty("DATABASE_PASSWORD");
            String dbName = propFile.getProperty("DATABASE_CATALOGNAME");
            JDBCConnectionSetting connectionSetting =
                    new JDBCConnectionSetting();
            connectionSetting.setConnectionURL("jdbc:mysql://" + dbUrl + "/" +
                    dbName);
            connectionSetting.setDialect("org.hibernate.dialect.MySQLDialect");
            connectionSetting.setDriverClass("com.mysql.jdbc.Driver");

            connectionSetting.setUserName(dbUserName);
            connectionSetting.setPassword(dbPassword);
            try {
                org.testis.orm.manager.TestisDbPersistentManager.setJDBCConnectionSetting(connectionSetting);
            } catch (PersistentException ex) {
                ex.printStackTrace();
            }
        }

    }
}